Are There Problems Reading a Multi-byte Counter?

Reading an active multi-byte counter or timer with an 8-bit processor poses some potential problems. If done incorrectly, the timer can seemingly jump backwards or skip values!

Consider a 16-bit or two-byte counter containing the decimal value 24 in the most-significant byte (MSB) and 255 in the least-significant byte (LSB). If our application program reads the low-byte (LSB) first, we store the value LSB=255. In the process of reading the LSB, the counter continues to count. The value in the LSB has now 'rolled-over' into the MSB. The counter now contains MSB=25 and LSB=0. If our program now reads the MSB, we store the value MSB=25. At this point, our program assumes that the counter contains MSB=25, LSB=255--a perfectly legitimate value.

 

Period

MSB

LSB

Action

Software View

1

24

255

Read LSB

MSB=?, LSB=255

2

25

00

Read MSB

MSB=25, LSB=255

3

25

01

Read LSB

MSB=25, LSB=01

4

25

02

Read MSB

MSB=25, LSB=01

 

However, if the program then reads the counter again, it reads the LSB as 1 (it incremented since we read it), and the MSB as 25. The timer or counter seems to jump backwards in time! A Triscend E5 Configurable System-on-Chip (CSoC) device is capable of many things but time travel is not one of them.

The best way to read an active, multi-byte counter is to disable the counter before reading it. However, this is not possible in many applications, especially those that are tracking a time period. Another option is to capture a 'snapshot' of the counter value in a register. Timer 2 within the 8051 microcontroller has a capture option. Unfortunately, Timer 0 and Timer 1 do not. 'Soft' module implementations with a capture option would require additional logic resources.

The next best was is to read the counter from most-significant to least-significant byte. The upper bytes of a multi-byte counter change infrequently compared to the least-significant byte (LSB). The LSB is where all the action occurs, so read it last. To handle the case where the LSB value 'rolls over' into the next byte, perform the multi-byte read as shown below. Read from MSB to LSB. The LSB+1 byte is read twice - once before and once after reading the LSB byte. If the value of LSB+1 is the same during both read operations, then you have a valid counter value. However, if LSB+1 is different, then the least-significant byte (LSB) 'rolled over'. Your application program should re-read the counter.

The example 8051 assembly code below shows how to read a 16-bit timer value.  The counter is assumed to be located in SFR memory.

This situation occurs more often than you might think. In the 8051 microcontroller, Timer 0, Timer 1, and Timer 2 all have 16-bit modes. Likewise, you might create your own multi-byte timers/counters using Configurable System Logic (CSL) logic resources.

You might think the compiler is smart enough to handle this situation. However, none of the compilers tested handled this situation correctly, even after declaring the counter as an int or long variable in 'C'. Also, be sure to declare the counter variable as volatile in 'C' to avoid potential undesired compiler optimizations. We want the current value of the LSB+1 byte during both read operations. We don't want to re-read the value already stored away in one of the 8051's registers.

®

© 2001 by Triscend Corporation.  All rights reserved.